package httpserver;

import httpserver.general.HTTPMethods;
import httpserver.request.Request;
import httpserver.response.Response;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;

public class Engine {

    private static class Processor implements Runnable {

        private Socket socket;

        private Processor(Socket socket) throws Throwable {
            this.socket = socket;
        }

        public void run() {
            InputStream is = null;
            OutputStream os = null;
            int statusCode = 200;
            String method = "";
            String customMessage = "";
            String authParams = "";
            boolean cookie = false;
            //boolean closed = false;
            String requestedURI = "";
            try {
                is = socket.getInputStream();
                os = socket.getOutputStream();
                socket.setSoTimeout(10000);
            } catch(IOException exc){
                exc.printStackTrace();
            }
            //while(true){
                try{
                    Request request = new Request(is);
                    request.read();
                    //closed = request.isConnectionClosed();
                    //if(closed) System.out.println("CLOSED\n");
                    requestedURI = request.getRequestedURI();
                    method = request.getMethod();
                    authParams = request.getAuthParams();
                    cookie = request.hasAuthCookie();
                    if(method.equals(HTTPMethods.POST)) {
                        customMessage = request.getCustomMessage();
                        //System.out.println(customMessage);
                    }
                } catch(HTTPException hexc){
                    statusCode = hexc.getStatusCode();
                    hexc.printStackTrace();
                } catch(IOException exc) {
                    exc.printStackTrace();
                    //System.exit(1);
                }
                try{
                    Response response = new Response(os, method, requestedURI);
                    response.setAuthParams(authParams);
                    if(!method.equals(HTTPMethods.POST)){
                        response.write(statusCode);
                    } else {
                        response.writeCustomMessage(customMessage);
                    }

                    //if(closed){
                    //    closed = false;
                    //    break;
                    //}
                } catch(Exception exc){
                    exc.printStackTrace();
                }
            //}
            try {
                socket.close();
            } catch (IOException exc) {
                exc.printStackTrace();
            }

            System.out.println("Client " + socket.getInetAddress()
                    + ":" + socket.getPort() + " processing finished");
        }

    }
    
    public static void main(String[] args) throws Throwable {
        if(args.length==1&&args[0].equals("help")){
            System.out.println("Usage:\njava -jar HTTPServer.jar port" +
                    "\nWhere\nport = (0, 65535)");
            System.exit(1);
        }
        int port = 80;
        if(args.length==1){
            port = Integer.parseInt(args[0]);
        }
        ServerSocket serverSocket = new ServerSocket(port, 0, InetAddress.getLocalHost());

        while (true) {
            Socket s = serverSocket.accept();
            System.out.println("Client " + s.getInetAddress()
                    + ":" + s.getPort() + " accepted");
            new Thread(new Processor(s)).start();
        }
    }
}